using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;

/* LOG 
July 7th, 2009: 
 * Added Glow animation via styles. However, this is causing problems with some bodies. They disappear.
July 8th, 2009: 
 * Added animation to all the shapes. Opacity Property was changed. Removed glow animation.
July 12th, 2009: 
 * Successfully added the callbacks for the collision. Had to create materials and set collision callbacks
July 13th, 2009: 
 * Figured out how to set the material in order to call the contact methods.
 * Attempted to add sound. Tried both the sound player and the media player. However, none will really work since
 * I need many sounds to be played simultaneously.
 * Added in logic to look for strength of the contact before playing the sound. Otherwise all the rolling will create
 * sound effects as well. However, the way I am checking is a hack at the moment
July 14th, 2009:
 * Found the IrrKlang sound engine
 * Incorporated it, and created 100 alias sounds that I round robin around when I need to generate a click sound
 * Added in an explosion sound when user clicks on an object to remove it from the world.
 * Need to find a better click sound --- like two plastic tiles.
July 15th, 2009:
 * Fixed the marshalling bug in the wrapper. This was related to passing arrays by reference. Applied to pretty
 * much all the GET procedures on the BODY (BodyManipulation.CS) like Velocity, Omega, etc.
 * Played more with the sound generation. Still not happy.
 * Added in code to nil out all the forces during drag. Mostly works. There is still some force being applied that
 * prevents the bodies from overlapping each other.
July 18th, 2009:
 * Body can rotate. Press middle button, then use scroll wheel. When done, press middle button again!
 * Rotating the car does not work very well. Will need to add code to rotate the wheels with it.
July 19th, 2009:
 * Changed Add Impulse Procedure to use the point vector as defined in the body matrix offset.x, offset.y, offset.z
 * This give a much better application of the force on the body. Also change impulse force from 10 to 8.
 * There was another bug in the force application that was causing it to be applied twice. Fixed that as well.
 * Added image brushes for static rectangle, rectangle and polygon.
 * Getting close to having all the tools to start on the word game. 

 
 * */
 
namespace WPFPhysics1
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>

	public partial class Window1 : System.Windows.Window
	{
		public Window1()
		{
			InitializeComponent();

			ObjectDataProvider data = Resources[ "bodies" ] as ObjectDataProvider;
			Bodies bodies = data.Data as Bodies;
			bodies.SetPlatforms();
			bodies.DropObjects( BodyType.Ellipse );
		}

		protected void Drop_Click( object sender, RoutedEventArgs e )
		{
			ObjectDataProvider data = Resources[ "bodies" ] as ObjectDataProvider;
			Bodies bodies = data.Data as Bodies;
			Button button = sender as Button;

			if ( bodies != null && button != null )
			{
				switch ( button.Name )
				{
					case "rectangle":

						bodies.DropObjects( BodyType.Rectangle );
						break;

					case "ellipse":

						bodies.DropObjects( BodyType.Ellipse );
						break;

					case "polygon":

						bodies.DropObjects( BodyType.Polygon );
						break;

					case "car":

						bodies.DropObjects( BodyType.Car );
						break;

					case "platforms":

						bodies.SetPlatforms();
						break;
				}
			}
		}

        private void Drop_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;
            Button button = sender as Button;
            int dim1=0;

            if (bodies != null && button != null && e.Delta !=0)
            {
                switch (button.Name)
                {
                    case "rectangle":
                        dim1 = (int)BodyType.Rectangle;
                        break;

                    case "ellipse":
                        dim1 = (int)BodyType.Ellipse;
                        break;

                    case "polygon":
                        dim1 = (int)BodyType.Polygon;
                        break;

                    case "car":
                        dim1 = (int)BodyType.Car;
                        break;

                    default:
                        return;
                }
                double value = objectcountslider.Value + Math.Abs(e.Delta) / e.Delta;

                value = Math.Max(value, objectcountslider.SelectionStart);
                value = Math.Min(value, objectcountslider.SelectionEnd);

                objectcountslider.Value = (int)value;
                bodies.BodyCountSliderData[dim1, (int)BodyCountSliderType.current] = (int)value;
            }

        }

        private void Drop_MouseEnter(object sender, MouseEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;
            Button button = sender as Button;
            int dim1=0;

            if (bodies != null && button != null)
            {
                switch (button.Name)
                {
                    case "rectangle":
                        dim1 = (int)BodyType.Rectangle;
                        break;

                    case "ellipse":
                        dim1 = (int)BodyType.Ellipse;
                        break;

                    case "polygon":
                        dim1 = (int)BodyType.Polygon;
                        break;

                    case "car":
                        dim1 = (int)BodyType.Car;
                        break;

                    default:
                        return;
                }

                objectcountslider.Visibility = Visibility.Visible;
                objectcountslider.IsSelectionRangeEnabled = true;
                //set the slider value
                objectcountslider.Value = bodies.BodyCountSliderData[dim1, (int)BodyCountSliderType.current];
                objectcountslider.SelectionEnd = bodies.BodyCountSliderData[dim1, (int)BodyCountSliderType.max];
                objectcountslider.SelectionStart = bodies.BodyCountSliderData[dim1, (int)BodyCountSliderType.min];
                objectcountslider.Background = Brushes.Red;
            }
        }

        private void Drop_MouseLeave(object sender, MouseEventArgs e)
        {

            objectcountslider.Background = Brushes.PaleGoldenrod;
            objectcountslider.Visibility = Visibility.Hidden;

        }

        private void myWindowMouseMoveHandler(object sender, MouseEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;

            if (bodies.BodyAction == BodyActionType.dragstart)
            {
                bodies.mouseCurrentLocation = e.GetPosition(Application.Current.MainWindow);
                bodies.UIBodyAction();
            }
        }

        private void myWindowWheelHandler(object sender, MouseWheelEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;

            if (bodies.BodyAction == BodyActionType.rotate)
            {
                bodies.mouseWheelDelta = (Math.Abs(e.Delta) / e.Delta)*5;
                bodies.UIBodyAction();
            }
        }

        private void myWindowMouseDownHandler(object sender, MouseButtonEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;

            if (e.ChangedButton == MouseButton.Middle)
            {
                if (bodies.mouseWheelBodyId != "")
                {
                    if (bodies.BodyAction == BodyActionType.rotate)
                    {
                        bodies.BodyAction = BodyActionType.rotatestop;
                        bodies.UIBodyAction();
                    }
                    else
                    {
                        bodies.BodyAction = BodyActionType.rotate;
                    }
                }
            }
        }

        private void myWindowMouseUpHandler(object sender, MouseButtonEventArgs e)
        {
            ObjectDataProvider data = Resources["bodies"] as ObjectDataProvider;
            Bodies bodies = data.Data as Bodies;

            if (e.ChangedButton == MouseButton.Right)
            {
                if (e.ButtonState == MouseButtonState.Released)
                {
                    if (bodies.BodyAction == BodyActionType.dragstart)
                    {
                        bodies.BodyAction = BodyActionType.dragstop;
                        bodies.UIBodyAction();
                    }
                }
            }
        }
	}
}